package main

import "fmt"

// 定义接口类型
type Humaner interface {
	// 方法，只有声明，没有实现  由别的类型实现
	sayhi()
}
type Student struct {
	name string
	id   int
}
type Teacher struct {
	addr  string
	group string
}

type Mystring string

func (tmp *Student) sayhi() {
	fmt.Printf("Studentp[%s, %d ] say hi \n", tmp.name, tmp.id)
}
func (tmp *Teacher) sayhi() {
	fmt.Printf("Teacher[%s, %s ] say hi \n", tmp.addr, tmp.group)
}
func (tmp *Teacher) sayhi2() {
	fmt.Printf("Teacher[%s, %s ] say hi \n", tmp.addr, tmp.group)
}
func (tmp *Mystring) sayhi() {
	fmt.Printf("mystring say hi %v \n", *tmp)
}

// 定义一个普通函数，函数的参数为接口类型
func WhoSayHi(i Humaner) {
	i.sayhi()
}

func main() {
	s := Student{"xdc", 2}
	t := Teacher{"afd", "af"}
	var str Mystring = "hello world"

	WhoSayHi(&s)
	WhoSayHi(&t)
	WhoSayHi(&str)

	var x []Humaner = make([]Humaner, 3)
	x[0] = &s
	x[1] = &t
	x[2] = &str

	for _, humaner := range x {
		WhoSayHi(humaner)
	}

	ttt := make([]*int, 3)
	fmt.Println(ttt)
}

func main01() {
	// 定义接口类型的变量
	var i Humaner

	// 只是实现了此接口方法的类型，那么合格类型的变量（接收者类型） 就可以给i赋值

	s := Student{
		name: "xdc",
		id:   1,
	}
	i = &s
	s.sayhi()

	t := Teacher{
		addr:  "beijing",
		group: "一班",
	}
	i = &t
	t.sayhi()

	var my Mystring = "hhh"
	i = &my
	i.sayhi()
}
